package com.macro.douyinpay;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.List;
import java.util.Set;

/**
 * @ClassName：Test
 * @Author: MACRO
 * @Date: 2024/9/12 23:35
 * @Description: TODO
 */

public class Test {
    static String selectAccountSelector = "#root > div > div.page-box.douyin > div > div.user-info > div.btn";
    //最终超时:您的订单已超时，请返回下单页面重新发起支付
    String finalPayTimeoutTips="body > div > div > div.bounce-container > div.modal-wrapper > div > div.title";
    //lenovo电脑浏览器驱动路径
    static String basePath = "E:\\test\\chrome-win64\\";
    static String driverPath = basePath + "chromedriver.exe";
    static String userDataPath = "E:\\test\\userData\\Default";
    //    static String openUrl = "https://blog.csdn.net/";
    static String openUrl = "https://www.douyin.com/pay";
    static WebDriver driver;

    public static void main(String[] args) throws InterruptedException {
        //加载驱动 TODO使用设计模式加载不同驱动
        loadDriver();
        driver.get(openUrl);
        //判断是否未登录
        Thread.sleep(5000);
        //根据是否登录执行不同逻辑
        ifLogin();
    }

    /**
     * 判断指定的元素是否存在于页面上。
     *
     * @param driver   WebDriver实例
     * @param selector CSS选择器
     * @return 如果元素存在返回true，否则返回false
     */
    public static boolean elementExists(WebDriver driver, String selector) {
        // 使用findElements方法查找元素
        List<WebElement> elements = driver.findElements(By.cssSelector(selector));
        // 如果列表不为空，则元素存在
        return !elements.isEmpty();
    }

    /**
     * 根据是否登录执行不同逻辑
     */
    public static void ifLogin() {
        //未登录时，二维码顶部提示语：扫码获取充值抖音号
        String unLoginTopTips = "#root > div > div.page-box.douyin > div > div.login-container > div.login-title";
        boolean exists = elementExists(driver, "#root > div > div.page-box.douyin > div > div.login-container > div.login-title");

        if (exists) {
            printColored("元素存在 未登录");
            waitForLogin();
        } else {
            printColored("元素不存在 已登录");
            handleMain();
        }
//        System.out.println(unLoginTopTipsElement.getText());
//        if (null != unLoginTopTipsElement) {
//            //未登录调用登录方法
//            waitForLogin();
//        } else {
//            //已经登录，开始执行主流程
//            handleMain();
//        }
    }

    public static void waitForLogin() {
        //登陆后，切换账号
        String hadLoginSelector = "#root > div > div.page-box.douyin > div > div.user-info > div.btn";
        //监听120秒，直到hadLoginSelector出现停止监听，调用handleMain()方法;如果超时还未出现，则
        // 设置最长等待时间为120秒
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(120));
        try {
            // 等待直到hadLoginSelector元素出现
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(hadLoginSelector)));
            // 元素出现后，调用handleMain方法
            handleMain();
        } catch (org.openqa.selenium.TimeoutException e) {
            // 如果超时还未出现，则执行这里的代码
            printColored("超时未出现");
            // 这里可以添加超时后的逻辑，例如重试、记录日志、抛出异常等
            printColored("未出现则重新调用判断是否登录逻辑");
        }

    }

    public static void watch(String cssSelector){
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(120));
        try {
            // 等待直到 cssSelector 元素出现
            wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(cssSelector)));
            // 元素出现后，调用handleMain方法
            handleMain();
        } catch (org.openqa.selenium.TimeoutException e) {
            // 如果超时还未出现，则执行这里的代码
            printColored("超时未出现");
            // 这里可以添加超时后的逻辑，例如重试、记录日志、抛出异常等
            printColored("未出现则重新调用判断是否登录逻辑");
        }
    }

    // ANSI转义序列前缀
    private static final String ANSI_RESET = "\u001B[0m";
    private static final String ANSI_GREEN = "\u001B[32m";
    private static final String ANSI_RED = "\u001B[31m";
    private static final String ANSI_YELLOW = "\u001B[33m";

    /**
     * 打印带有颜色的字符串。
     *
     * @param text  要打印的字符串
     * @param color 颜色代码
     */
    public static void printColored(String text) {
        System.out.println(ANSI_GREEN + text + ANSI_RESET);
    }


    public static void handleMain()   {
        try {
            System.out.println("已经登录，开始请求接口查询待充值的订单");
            while (true) {
                Thread.sleep(5000);
                printColored("开始查询待充值订单......");
                Order unPaidOrder = getUnPaidOrder();
                if(null !=unPaidOrder){
                    //判断是否存在切换账号。如果有则是该号第一次；没有则为多次，按钮为确认账号
                    selectAccExists();
                    //输入抖音id
                    enterId(unPaidOrder.getDouyinId());
                    printColored("【输入抖音id】成功");
                    Thread.sleep(1000);
                    //输入id后，点击确认账号
                    clickComfirmAccount();
                    printColored("【确认账号】成功");
                    Thread.sleep(1000);
                    //点击自定义金额
                    clickSelfDefPrice();
                    Thread.sleep(1000);
                    //输入钻石数量
                    inputDiamondAmount(unPaidOrder.getCoinAmount());
                    printColored("【输入钻石数量】成功");
                    Thread.sleep(1000);
                    //点击-立即充值
                    clickNowToPay();
                    Thread.sleep(2000);
                    //获取支付二维码
                    getPayUrlSvg();
                }

            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    public static void clickNowToPay() throws InterruptedException {
        String nowToPaySelector="#root > div > div.page-box.douyin > div > div.pay-info.douyin > div.pay-button > span";
        moveAndClick(nowToPaySelector);
    }
    /**获取支付二维码-SVG格式*/
   public static void getPayUrlSvg(){
       String payUrlSelector="body > div > div > div.bounce-container > div.bounce-content > div > div:nth-child(1) > div.pay > div.pay-method > div > div > div > div > div.info-content-qrcode > div > svg";
       WebElement element = driver.findElement(By.cssSelector(payUrlSelector));
       // 获取SVG的outerHTML
       String svgContent = element.getAttribute("outerHTML");

       // 将SVG内容保存到文件
       File svgFile = new File("E:\\test\\downloaded.svg");
       try (FileOutputStream fos = new FileOutputStream(svgFile)) {
           fos.write(svgContent.getBytes(StandardCharsets.UTF_8));
       } catch (IOException e) {
           e.printStackTrace();
       }

   }
    public  static  void payUrlIfTimeout(){
       String urlTimeoutTipsSelector="body > div > div > div.bounce-container > div.bounce-content > div > div:nth-child(1) > div.pay > div.pay-method > div > div > div > div > div.info-content-limit > div.info-content-limit-countdown > span";
       String clickRefreshSelector="body > div > div > div.bounce-container > div.bounce-content > div > div:nth-child(1) > div.pay > div.pay-method > div > div > div > div > div.info-content-qrcode.expired > div.info-content-qrcode-expire > div > span.button-text";

    }
    public static void selectAccExists() throws InterruptedException {
        boolean selectAccBtnExists = elementExists(driver, selectAccountSelector);
        if (selectAccBtnExists) {
            printColored("元素存在 当前账号收充值");
            //点击切换账号
            clickSelectAccount();
            Thread.sleep(1000);
        } else {
            printColored("元素不存在 当前账号二次充值");

        }
    }
    public static void inputDiamondAmount(Integer amount){
        String selector="#root > div > div.page-box.douyin > div > div.combo-list > div.customer-recharge.active > div.money-container > div > input";
        WebElement element = driver.findElement(By.cssSelector(selector));
        element.click();
        element.sendKeys(amount.toString());
    }
    public static void clickSelfDefPrice(){
        String selector="#root > div > div.page-box.douyin > div > div.combo-list > div.customer-recharge > span.name";
        WebElement element = driver.findElement(By.cssSelector(selector));
        element.click();
    }
    public static void clickComfirmAccount(){
        String confirmAccSelector="#root > div > div.page-box.douyin > div > div.select-wrap > div.input-wrap > div.confirm-btn";
        WebElement element = driver.findElement(By.cssSelector(confirmAccSelector));
        element.click();
    }
    public static void enterId(String id){

        String inputSelector="#root > div > div.page-box.douyin > div > div.select-wrap > div.input-wrap > div.input > input[type=text]";
        //键盘输入
        WebElement element = driver.findElement(By.cssSelector(inputSelector));
        element.sendKeys(id);
    }
    /**单击-切换账号*/
    public static void clickSelectAccount() throws InterruptedException {
        moveAndClick(selectAccountSelector);
    }
    public static void startToAutoPay() {

    }

    public static Order getUnPaidOrder() {
        printColored("查询有无订单!");
        Order order = new Order();
        order.setId("1");
        order.setCoinAmount(10);
        order.setDouyinId("1254498151");
        printColored("查询到订单:" + order);
        return order;
    }

    /**
     * @param cssSelector:css选择器
     * @author macro
     * @description 移动并单击
     * @time 2024/9/13 12:03
     */
    public static void moveAndClick(String cssSelector) throws InterruptedException {
        // 等待元素加载完成
        WebElement element = driver.findElement(By.cssSelector(cssSelector));
        // 创建Actions对象
        Actions actions = new Actions(driver);
        // 移动到元素并点击
        actions.moveToElement(element).click().perform();
        Thread.sleep(300);
    }


    public static void loadDriver() throws InterruptedException {
        //指定路径
        System.setProperty("webdriver.chrome.driver", driverPath);
        // 创建一个Chrome浏览器实例
        ChromeOptions chromeOptions = new ChromeOptions();
        //解决 403 出错问题
        chromeOptions.addArguments("--remote-allow-origins=*");
        // 设置用户数据目录
        chromeOptions.addArguments("user-data-dir=E:\\test\\userData");
        driver = new ChromeDriver(chromeOptions);
    }

    public static void wait2() {
        // Google 搜索结果由 JavaScript 动态渲染
        // 等待页面加载完毕，超时时间设为10秒
        (new WebDriverWait(driver, Duration.ofSeconds(1000))).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver d) {
                return d.getTitle().toLowerCase().startsWith("cheese!");
            }
        });

    }

    public static void forEachCookies() {


        // 输出当前 url 所有可用的 cookie
        Set<Cookie> allCookies = driver.manage().getCookies();
        for (Cookie loadedCookie : allCookies) {
            System.out.println(String.format("%s -> %s", loadedCookie.getName(), loadedCookie.getValue()));
            Cookie cookie = new Cookie(loadedCookie.getName(), loadedCookie.getValue());
            driver.manage().addCookie(cookie);
        }

    }

    /**
     * 当前是否登录（根据指定的CSS选择器是否存在于页面上）
     */
//    public static void ifUnLogin() {
//        // 构建CSS选择器
//        String selector = "#root > div > div.page-box.douyin > div > div.login-container > div.login-title";
//        // 检查选择器是否存在
//        boolean exists = !driver.findElements(By.cssSelector(selector)).isEmpty();
//        // 输出结果
//        System.out.println("选择器 '" + selector + "' 存在: " + exists);
//        //等待-登陆成功后的切换账号按钮
////        wait1();
//        //
//
//    }

    public static void wait1() {
        String selectAccSelector = "#root > div > div.page-box.douyin > div > div.user-info > div.btn";
        // 创建WebDriverWait实例，设置超时时间
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3000));
        // 循环检查选择器是否出现
        while (true) {
            // 检查选择器是否出现
            boolean isDisplayed = wait.until(driver -> {
                try {
                    return driver.findElement(By.cssSelector(selectAccSelector)).isDisplayed();
                } catch (org.openqa.selenium.NoSuchElementException e) {
                    return false;
                }
            });

            if (isDisplayed) {
                System.out.println("出现了");
                // 选择器出现，调用test方法
                test();
                break; // 跳出循环
            } else {
                // 选择器没有出现，打印消息并继续等待
                System.out.println("选择器 '" + "' 还没有出现，继续等待...");
            }
        }
    }


    public static void test() {
        System.out.println("选择器出现，执行测试方法。");
        // 在这里添加你的测试代码
    }


    /**
     * 未登录则一直监听
     */
    public static void unLoginWatch() {

    }
}
